﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
using System.Xml.Linq;
using Microsoft.Win32;
using ZuluTrade.Core;
using Path = System.IO.Path;
using ZuluTrade.Graphic;
using System.Windows.Controls.DataVisualization.Charting;

namespace ZuluTrade
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private enum LineType{
            Raw,
            Average,
            Sum
        }

        #region Константы

        private static XNamespace SS = "urn:schemas-microsoft-com:office:spreadsheet";
        private static XNamespace O = "urn:schemas-microsoft-com:office:office";
        private static XNamespace X = "urn:schemas-microsoft-com:office:excel";
        #endregion

        #region Поля

        private Dictionary<String, List<ZuluRow>> providers = new Dictionary<String, List<ZuluRow>>();

        private Dictionary<LineType, List<ChartPoint>> lineData = new Dictionary<LineType, List<ChartPoint>>();
        #endregion

        public MainWindow()
        {
            InitializeComponent();
        }

        public static void ScrollToBottom(ListBox listbox)
        {
            if (listbox == null) throw new ArgumentNullException("listbox", "Argument listbox cannot be null");
            if (!listbox.IsInitialized) throw new InvalidOperationException("ListBox is in an invalid state: IsInitialized == false");

            if (listbox.Items.Count == 0)
                return;

            listbox.ScrollIntoView(listbox.Items[listbox.Items.Count - 1]);
        }

        #region Метод работы с xls файлами

        private List<XElement> OpenXls(String fileName){
            List<XElement> res = new List<XElement>();
            try{
                XDocument workbook = XDocument.Load(fileName);
                foreach (XElement worksheet in workbook.Descendants(SS + "Worksheet")){
                    IEnumerable<XElement> rows = worksheet.Descendants(SS + "Row");
                    foreach (var row in rows){
                        String bDate = "";
                        String eDate = "";
                        if (row.HasElements){
                            XElement beginDate = row.Elements(SS + "Cell").ToArray()[4];
                            XElement endDate = row.Elements(SS + "Cell").ToArray()[5];
                            if (beginDate.HasElements){
                                if (beginDate.Element(SS + "Data") != null)
                                    bDate = beginDate.Element(SS + "Data").Value;
                            }
                            if (endDate.HasElements){
                                if (endDate.Element(SS + "Data") != null)
                                    eDate = endDate.Element(SS + "Data").Value;
                            }

                            DateTime startDate = DateTime.MinValue;
                            DateTime stopDate = DateTime.MinValue;
                            if (DateTime.TryParse(bDate, out startDate))
                                if (DateTime.TryParse(eDate, out stopDate)){
                                    if ((this.dateBegin.SelectedDate <= startDate) &&
                                        (this.dateEnd.SelectedDate >= stopDate))
                                        res.Add(new XElement(row));
                                }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format("Ошибка загрузки Xls файла - {0}.  {1}", fileName, ex.Message), "Ошибка",
                                MessageBoxButton.OK, MessageBoxImage.Error);
            }
            finally { }
            return res;
            //Int32 ind = 0;
                //foreach (XElement row in rows)
                //{
                //    try{
                //        //listBox1.Items.Insert(0, ll);
                //        IEnumerable<XElement> cells = row.Descendants(ss + "Cell");

                //        foreach (XElement xx in cells)
                //        {
                //            ListBoxItem ll = new ListBoxItem();
                //            ll.Content = xx.Name + "-" + xx.Value;
                //            //listBox1.Items.Insert(0, ll);
                //        }
                       
                //    }
                //    catch (XmlException XmlErr)
                //    {
                //        ListBoxItem ll = new ListBoxItem();
                //        ll.Content = "*** Error:" + XmlErr.Message;
                //        //listBox1.Items.Insert(0, ll);
                //    }
                //    catch (Exception DefErr)
                //    {
                //        ListBoxItem ll = new ListBoxItem();
                //        ll.Content = "*** Error:" + DefErr.Message;
                //        //listBox1.Items.Insert(0, ll);

                //    }
                //}
        }

        private static List<ZuluRow> ReadXls(String fileName){
            //if (openedDate == null)
            //    openedDate = DateTime.MinValue;
            //if (closedDate == null)
            //    closedDate = DateTime.MaxValue;
            List<ZuluRow> res = new List<ZuluRow>();
            try{
                XDocument workbook = XDocument.Load(fileName);
                XName wsheet = SS + "Worksheet";
                XName rSheet = SS + "Row";
                foreach (XElement worksheet in workbook.Descendants(wsheet)){
                    Boolean isFirst = true;
                    foreach (var row in worksheet.Descendants(rSheet)){
                        // пропускаем первую строку
                        if (isFirst){
                            isFirst = false;
                            continue;
                        }
                        //String bDate = "";
                        //String eDate = "";
                        if (row.HasElements){
                            ZuluRow zr = ReturnZuluRow(SS + "Cell", SS + "Data",  row);
                            if (zr != null)
                                res.Add(zr);
                        }
                    }
                }
            }catch (Exception ex){
                MessageBox.Show(String.Format("Ошибка загрузки Xls файла - {0}.  {1}", fileName, ex.Message), "Ошибка",
                                MessageBoxButton.OK, MessageBoxImage.Error);
            }
            finally { }
            return res;
           
        }

        private static ZuluRow ReturnZuluRow(XName cell, XName data, XElement row){
            ZuluRow zRow = null;
            XElement[] els = row.Elements(cell).ToArray();
            try{
                zRow = new ZuluRow(){
                    //ProviderTicket = row.Elements(ss + "Cell").ToArray()[0].Element(ss + "Data").Value,
                    //Type = row.Elements(ss + "Cell").ToArray()[1].Element(ss + "Data").Value,
                    //Lots = Convert.ToDouble(row.Elements(ss + "Cell").ToArray()[2].Element(ss + "Data").Value),
                    //Currency = row.Elements(ss + "Cell").ToArray()[3].Element(ss + "Data").Value,
                    DateOpened = DateTime.Parse(els[4].Element(data).Value),
                    DateClosed = DateTime.Parse(els[5].Element(data).Value),
                    //PriceOpened = row.Elements(ss + "Cell").ToArray()[6].Element(ss + "Data").Value,
                    //PriceClosed = row.Elements(ss + "Cell").ToArray()[7].Element(ss + "Data").Value,
                    HighestProfit =
                        Convert.ToDouble(els[8].Element(data).Value),
                    WorstDrawdown =
                        Convert.ToDouble(els[9].Element(data).Value),
                    //Roll = row.Elements(ss + "Cell").ToArray()[10].Element(ss + "Data").Value,
                    TotalPips = Convert.ToDouble(els[11].Element(data).Value),
                    //NetProfitAndLoss = row.Elements(ss + "Cell").ToArray()[12].Element(ss + "Data").Value,
                    //LiveTrade = row.Elements(ss + "Cell").ToArray()[13].Element(ss + "Data").Value,
                    ProviderName = els[14].Element(data).Value,
                    AccumulatedPips = Convert.ToDouble(els[15].Element(data).Value),
                    //AccumulatedProfit = row.Elements(ss + "Cell").ToArray()[16].Element(ss + "Data").Value,
                };
            }catch(Exception ex){
                zRow = new ZuluRow(){
                    //ProviderTicket = row.Elements(ss + "Cell").ToArray()[0].Element(ss + "Data").Value,
                    //Type = row.Elements(ss + "Cell").ToArray()[1].Element(ss + "Data").Value,
                    //Lots = Convert.ToDouble(row.Elements(ss + "Cell").ToArray()[2].Element(ss + "Data").Value.Replace('.',',')),
                    //Currency = row.Elements(ss + "Cell").ToArray()[3].Element(ss + "Data").Value,
                    DateOpened = DateTime.Parse(els[4].Element(data).Value),
                    DateClosed = DateTime.Parse(els[5].Element(data).Value),
                    //PriceOpened = row.Elements(ss + "Cell").ToArray()[6].Element(ss + "Data").Value,
                    //PriceClosed = row.Elements(ss + "Cell").ToArray()[7].Element(ss + "Data").Value,
                    HighestProfit =
                        Convert.ToDouble(els[8].Element(data).Value.Replace('.', ',')),
                    WorstDrawdown =
                        Convert.ToDouble(els[9].Element(data).Value.Replace('.', ',')),
                    //Roll = row.Elements(ss + "Cell").ToArray()[10].Element(ss + "Data").Value,
                    TotalPips = Convert.ToDouble(els[11].Element(data).Value.Replace('.', ',')),
                    //NetProfitAndLoss = row.Elements(ss + "Cell").ToArray()[12].Element(ss + "Data").Value,
                    //LiveTrade = row.Elements(ss + "Cell").ToArray()[13].Element(ss + "Data").Value,
                    ProviderName = els[14].Element(data).Value,
                    AccumulatedPips = Convert.ToDouble(els[15].Element(data).Value.Replace('.', ',')),
                    //AccumulatedProfit = row.Elements(ss + "Cell").ToArray()[16].Element(ss + "Data").Value,
                };
            }

            return zRow;
        }
        #endregion

        #region методы

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClose_Click(object sender, RoutedEventArgs e){
            this.Close();
        }

        /// <summary>
        /// Добавить файлы в список.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnImport_Click(object sender, RoutedEventArgs e){
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "All Files (*.*)|*.*";
            openFileDialog1.Multiselect = true;
            // загружаем список устройств и таблиц
            if (openFileDialog1.ShowDialog().Value){
                Mouse.OverrideCursor = Cursors.Wait;
                Thread.CurrentThread.Priority = ThreadPriority.Highest;
                try{
                    foreach (var fileName in openFileDialog1.FileNames){
                        List<ZuluRow> xList = new List<ZuluRow>();
                        // загружаем файл в словарь
                        xList = ReadXls(fileName);
                        if (xList.Count > 0){
                            if (!this.providers.ContainsKey(xList[0].ProviderName)){
                                this.providers.Add(xList[0].ProviderName, xList);
                            }else{
                                //MessageBox.Show(String.Format("Данная система уже присутствует в списке: {0}.", xList[0].ProviderName), "Ошибка",
                                  // MessageBoxButton.OK, MessageBoxImage.Warning);
                            }
                        }
                    }
                }
                catch (Exception ex){
                    MessageBox.Show(String.Format("Ошибка загрузки Xls файла. {0}", ex.Message), "Ошибка",
                                   MessageBoxButton.OK, MessageBoxImage.Error);
                }
                finally{
                    this.lstFiles.Items.Clear();
                    foreach(var prov in this.providers){
                        this.lstFiles.Items.Add(prov.Key);
                    }
                    if (this.lstFiles.Items != null)
                        this.txtTotalFiles.Text = Convert.ToString(this.lstFiles.Items.Count);
                    Thread.CurrentThread.Priority = ThreadPriority.Normal;
                    Mouse.OverrideCursor = null;
                }
            }

        }  
        
        /// <summary>
        /// Удалить файл из списка.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDelete_Click(object sender, RoutedEventArgs e){
            List<String> items = new List<String>();
            foreach (var item in this.lstFiles.SelectedItems){
                items.Add((String)item);
            }
            foreach (var item in items){
                this.lstFiles.Items.Remove(item);
                this.providers.Remove(item);
            }
            this.txtTotalFiles.Text = Convert.ToString(this.lstFiles.Items.Count);
        }

        /// <summary>
        /// Выбрать строки по заданному интервалу.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelect_Click(object sender, RoutedEventArgs e){
            List<ZuluProvider> systems = new List<ZuluProvider>();
            if (this.lstFiles.Items != null){
                // верхняя и нижняя границы
                Nullable<Int32> lowBorder = null;
                Nullable<Int32> highBorder = null;
                Int32 border = 0;
                if (Int32.TryParse(this.txtLowBorder.Text, out border))
                    lowBorder = border;
                if (Int32.TryParse(this.txtHighBorder.Text, out border))
                    highBorder = border;

                // выбираем из файлов
                foreach (var providerName in this.providers.Keys){
                    ZuluProvider provider = GetProvider(providerName, lowBorder, highBorder);
                    if (provider != null)
                        systems.Add(provider);
                }
            }
           if (systems.Count > 0){
                IEnumerable view = systems.OrderByDescending(x => x.PipsSum);
                this.lstProvidersTable.ItemsSource = view;
            } else{
                this.lstProvidersTable.ItemsSource = null;
            }
        }

        private ZuluProvider GetProvider(String providerName, Nullable<Int32> lowBorder, Nullable<Int32> highBorder){
            List<ZuluRow> xList = SelectRows(providerName);
            if (xList == null)
                return null;
            // обрабатываем выбранные строки
            if (xList.Count > 0){
                Double highestProfit = xList.Max(x => x.HighestProfit);
                Double lowVal = xList.Min(x => x.WorstDrawdown);
                // определяем подходит ли по границам DD
                Boolean isSuit = true;
                if ((lowBorder != null) && (lowVal < lowBorder)){
                    isSuit = false;
                }
                if ((highBorder != null) && (lowVal > highBorder)){
                    isSuit = false;
                }
                // если провайдер подошел по границам DD
                if (!isSuit){
                    return null;
                }else{
                    // общая прибыль
                    Double accPips = xList[0].AccumulatedPips;
                    // общие убытки
                    Double deadLoss = (from x in xList
                                       where x.TotalPips < 0
                                       select x).Sum(x => x.TotalPips) / 10;
                    // максимальный убыток
                    Double minDeadLoss = 0;
                    try{
                       minDeadLoss = (from x in xList
                                      where x.TotalPips < 0
                                      select x).Min(x => x.TotalPips);
                    }catch(Exception ex){}
                    // если количество выбранных совпадает с количеством строк в файле, то не вычитаем
                    // а если не совпадает)
                    if (xList.Count > 1)
                        if (xList.Count != this.providers[providerName].Count){
                            accPips -= xList[xList.Count - 1].AccumulatedPips;
                        }
                    ZuluProvider provider = new ZuluProvider(){
                        Name = xList[0].ProviderName,
                        RowsSelected = xList.Count,
                        MaxHighestProfit = highestProfit,
                        MinWorstDrawdown = lowVal,
                        PipsSum = Math.Round(accPips, 3),
                        DeadLoss = deadLoss,
                        MinDeadLoss = minDeadLoss
                    };
                    return provider;
                }
            }
            return null;
        }

        private List<ZuluRow> SelectRows(String providerName) {
            // границы времени
            DateTime openedDate = this.dateBegin.SelectedDate ?? DateTime.MinValue;
            DateTime closedDate = this.dateEnd.SelectedDate ?? DateTime.MaxValue;
            List<ZuluRow> xList = new List<ZuluRow>();
            if (this.providers.ContainsKey(providerName)) {
                // выбираем строки попадающие под интервал
                xList = (from p in this.providers[providerName]
                                       where (p.DateOpened >= openedDate) && (p.DateClosed <= closedDate)
                                       select p).ToList();
            }
            return xList;
        }

        private void btnSaveAs_Click(object sender, RoutedEventArgs e){
            try{
                // диалоговое окно для открытия отчета
                SaveFileDialog saveFileDialog1 = new SaveFileDialog();
                saveFileDialog1.Filter = "CSV Files (*.csv)|*.csv";
                saveFileDialog1.Title = "Сохранить таблицу как...";
                // сохраняем отчет
                if (saveFileDialog1.ShowDialog().Value){
                    this.SaveAsCsv(saveFileDialog1.FileName, this.lstProvidersTable.ItemsSource);
                }
            }
            catch (Exception ex){
                MessageBox.Show(String.Format("Ошибка сохранения данных в файл. Проверьте доступен ли выбранный файл для записи.\n{0}", ex.Message), "Ошибка", MessageBoxButton.OK,
                    MessageBoxImage.Error);
            }
        }

        private void SaveAsCsv(String path, IEnumerable iEnumerable){
            FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
            try{
                // преобразуем отчет в CSV формат
                String str = ConvertToCSV(iEnumerable);
                Byte[] data = Encoding.GetEncoding(1251).GetBytes(str);
                fs.Write(data, 0, data.Length);
            }
            catch (Exception ex){
                throw new Exception("Ошибка экспортирования в CSV. " + ex.Message);
            }
            finally
            {
                fs.Close();
            }
        }

        private string ConvertToCSV(IEnumerable zuluProviders){
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("Дата начала;Дата окончания;Low;High");
            sb.AppendLine(String.Format("{0};{1};{2};{3}", this.dateBegin.SelectedDate != null ? this.dateBegin.SelectedDate.ToString() : "не установлено", this.dateEnd.SelectedDate != null ? this.dateEnd.SelectedDate.ToString() : "не установлено", this.txtLowBorder.Text, this.txtHighBorder.Text));
            sb.AppendLine();
            sb.AppendLine("Provider;Rows Selected;LPT;LLT;LLT Real;PROFIT;LOSS;PF;RAR;RAR real");
            foreach (ZuluProvider item in zuluProviders){
                sb.AppendLine(String.Format("{0};{1};{2};{3};{4};{5};{6};{7};{8};{9}", item.Name, item.RowsSelected, item.MaxHighestProfit,item.MinWorstDrawdown, item.MinDeadLoss, item.PipsSum, item.DeadLoss, item.ProfitFactor, item.RAR, item.RARreal));
            }
            return sb.ToString();
        }
        #endregion

        #region Graph

        private void btnGraph_Click(object sender, RoutedEventArgs e) {
            // берем выбранный provider
            ZuluProvider provider = this.lstProvidersTable.SelectedItem as ZuluProvider;
            if (provider != null) {
                // очищаем график
                this.ProfitLine.ItemsSource = null;
                this.AverageLine.ItemsSource = null;
                this.SumLine.ItemsSource = null;
                // запрашиваем данные
                List<ZuluRow> xList = SelectRows(provider.Name);
                if (xList == null)
                    return;
                if (xList.Count > 0) {
                    this.ProfitChart.Title = provider.Name;
                    // сортируем по дате
                    xList.Sort(CompareByDateClosed);
                    // простое отображение
                    List<ChartPoint> points = new List<ChartPoint>();
                    // усредненные данные
                    List<ChartPoint> averagePoints = new List<ChartPoint>();
                    // сумма
                    List<ChartPoint> sumValuePoints = new List<ChartPoint>();
                    // минимальная дата закрытия в списке сделок
                    DateTime minDate = xList.Min(x => x.DateClosed);
                    // интервал 1 день
                    TimeSpan interval = new TimeSpan(1, 0, 0, 0, 0);
                    Double averagePips = 0.0;
                    Double sumPips = 0.0;
                    Int32 cnt = 0;
                    DateTime itemClosed = DateTime.MinValue;
                    foreach (var item in xList) {
                        // простые значения
                        points.Add(new ChartPoint(item.DateClosed, item.TotalPips, Convert.ToString(item.TotalPips) + " ; " + item.DateClosed));
                        // средние значения
                        if ((minDate <= item.DateClosed) && (item.DateClosed <= (minDate + interval))) {
                            averagePips += item.TotalPips;
                            sumPips += item.TotalPips;
                            cnt++;
                        } else {
                            averagePoints.Add(new ChartPoint(itemClosed, Math.Round(averagePips / cnt, 2), Convert.ToString(Math.Round(averagePips / cnt, 2) + " ; " + itemClosed)));
                            sumValuePoints.Add(new ChartPoint(itemClosed, sumPips, Convert.ToString(sumPips + " ; " + itemClosed)));
                            minDate = item.DateClosed;
                            cnt = 1;
                            averagePips = item.TotalPips;
                            sumPips += item.TotalPips;
                        }
                        itemClosed = item.DateClosed;
                    }
                    // добавляем последние усредненные значения
                    averagePoints.Add(new ChartPoint(itemClosed, Math.Round(averagePips / cnt, 2), Convert.ToString(Math.Round(averagePips / cnt, 2) + "; " + itemClosed)));
                    sumValuePoints.Add(new ChartPoint(itemClosed, sumPips, Convert.ToString(sumPips + " ; " + itemClosed)));

                    this.lineData.Clear();
                    this.lineData.Add(LineType.Raw, points);
                    this.lineData.Add(LineType.Average, averagePoints);
                    this.lineData.Add(LineType.Sum, sumValuePoints);
                    // отображаем линии
                    CheckBox chbx = null;
                    foreach (LegendItem item in this.ProfitChart.LegendItems) {
                        chbx = (CheckBox)item.Template.FindName("chbxRaw", item);
                        if (chbx != null)
                            chbx.IsChecked = false;
                        chbx = (CheckBox)item.Template.FindName("chbxAverage", item);
                        if (chbx != null)
                            chbx.IsChecked = false;
                        chbx = (CheckBox)item.Template.FindName("chbxSum", item);
                        if (chbx != null) {
                            chbx.IsChecked = true;
                            // отрисовываем суммированные данные
                            chbSeries3_Click(chbx, null);
                        }
                    }
                }
            }
        }

        private static Int32 CompareByDateClosed(ZuluRow z1, ZuluRow z2){
            if (z1.DateClosed == z2.DateClosed)
                return 0;
            else if (z1.DateClosed > z2.DateClosed)
                return 1;
            else
                return -1;
        }

        /// <summary>
        /// Save graph in file 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItem_Click(object sender, RoutedEventArgs e) {
            try {
                RenderTargetBitmap rtb = new RenderTargetBitmap((int)this.ProfitChart.ActualWidth, (int)this.ProfitChart.ActualHeight, 96, 96, PixelFormats.Pbgra32);
                rtb.Render(this.ProfitChart);
                BmpBitmapEncoder bmp = new BmpBitmapEncoder();
                bmp.Frames.Add(BitmapFrame.Create(rtb));
                SaveFileDialog saveFileDialog1 = new SaveFileDialog();
                saveFileDialog1.Filter = "Bmp files (*.bmp)|*.bmp|All files (*.*)|*.*";
                if (saveFileDialog1.ShowDialog().Value) {
                    using (System.IO.Stream stream = System.IO.File.Create(saveFileDialog1.FileName)) {
                        bmp.Save(stream);
                    }
                }
            } catch (Exception ex) {
                MessageBox.Show("Ошибка сохранения изображения в файл. " + ex.Message, "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// Copy graph in buffer
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItem_Click_1(object sender, RoutedEventArgs e) {
            try {
                RenderTargetBitmap rtb = new RenderTargetBitmap((int)this.ProfitChart.ActualWidth, (int)this.ProfitChart.ActualHeight, 96, 96, PixelFormats.Pbgra32);
                rtb.Render(this.ProfitChart);
                Clipboard.SetImage(rtb);
            } catch (Exception ex) {
                MessageBox.Show("Ошибка копирования изображения в буфер обмена. " + ex.Message, "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        } 
        #endregion

        /// <summary>
        /// Show raw profit line
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chbSeries1_Checked(object sender, RoutedEventArgs e) {
            CheckBox chBox = sender as CheckBox;
            if (chBox.IsChecked.Value) {
                if (this.lineData.ContainsKey(LineType.Raw)) {
                    this.ProfitLine.ItemsSource = this.lineData[LineType.Raw];
                    this.ProfitLine.Visibility = System.Windows.Visibility.Visible;
                }
            } else {
                this.ProfitLine.ItemsSource = null;
                this.ProfitLine.Visibility = System.Windows.Visibility.Hidden;
            }
        }

        /// <summary>
        /// Show average line
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chbSeries2_Checked(object sender, RoutedEventArgs e) {
            CheckBox chBox = sender as CheckBox;
            if (chBox.IsChecked.Value) {
                if (this.lineData.ContainsKey(LineType.Average)) {
                    this.AverageLine.ItemsSource = this.lineData[LineType.Average];
                    this.AverageLine.Visibility = System.Windows.Visibility.Visible;
                }
            } else {
                this.AverageLine.ItemsSource = null;
                this.AverageLine.Visibility = System.Windows.Visibility.Hidden;
            }
        }

        /// <summary>
        /// Show sum line
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chbSeries3_Click(object sender, RoutedEventArgs e) {
            CheckBox chBox = sender as CheckBox;
            if (chBox.IsChecked.Value) {
                if (this.lineData.ContainsKey(LineType.Sum)) {
                    this.SumLine.ItemsSource = this.lineData[LineType.Sum];
                    this.SumLine.Visibility = System.Windows.Visibility.Visible;
                }
            } else {
                this.SumLine.ItemsSource = null;
                this.SumLine.Visibility = System.Windows.Visibility.Hidden;
            }
        }
    }
}
